#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <event2/event.h>
#include <event2/listener.h>
#include <event2/bufferevent.h>
#include <map>
#include <vector>

#include "protocol/include/log.hpp"

#include "protocol/include/MDQPParser.hpp"

const int TCP_PORT = 12345;

static MDQPParser *parser = nullptr;

static struct event_base *base = nullptr;
static struct evconnlistener *listener = nullptr;

void tcp_exit();

static void on_heartbeat(evutil_socket_t fd, short event, void *arg)
{
    struct bufferevent *bev = (struct bufferevent *)arg;
    MDQPHeader *header = parser->getMDQP();
    if (header)
    {
        bufferevent_write(bev, (void *)header, header->length + sizeof(MDQPHeader));
        // LOG("send mdqp\n");
    }
    else
    {
        // LOG("no more mdqp\n");
    }
}

static void on_error(struct bufferevent *bev, short error, void *ctx)
{
    if (error & BEV_EVENT_EOF)
    {
        printf("Connection closed\n");
    }
    else if (error & BEV_EVENT_ERROR)
    {
        printf("Error occurred\n");
    }
    bufferevent_free(bev);
}

static void on_accept(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *address, int socklen, void *ctx)
{
    struct event_base *base = evconnlistener_get_base(listener);
    struct bufferevent *bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);

    struct event *heartbeat_event = event_new(base, -1, EV_PERSIST, on_heartbeat, bev);
    struct timeval heartbeat_interval = {0, 5 * 1000}; // 5毫秒一次
    event_add(heartbeat_event, &heartbeat_interval);

    LOG("New connection\n");
}

int tcp_main()
{
    parser = new MDQPParser("/home/wang/Documents/github/internship/shang-hai-qi-huo/tcp_20230628.pcap");
    parser->parse();

    struct sockaddr_in sin;

    base = event_base_new();
    if (!base)
    {
        fprintf(stderr, "Could not initialize event base\n");
        return 1;
    }

    memset(&sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = htonl(INADDR_ANY);
    sin.sin_port = htons(TCP_PORT);

    // 创建监听器，监听指定端口
    listener = evconnlistener_new_bind(base, on_accept, NULL,
                                       LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE, -1,
                                       (struct sockaddr *)&sin, sizeof(sin));
    if (!listener)
    {
        fprintf(stderr, "Could not create listener\n");
        return 1;
    }

    event_base_dispatch(base);

    evconnlistener_free(listener);
    event_base_free(base);

    delete parser;
    parser = NULL;
    return 0;
}

void tcp_exit()
{
    LOG("tcp exitint\n");
    // 停止事件循环
    event_base_loopexit(base, NULL);

    // 关闭监听器
    evconnlistener_free(listener);

    // 清理资源
    event_base_free(base);
    if (parser)
    {
        delete parser;
        parser = NULL;
    }
    return;
}